package com.dobest.aspectdemo;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;


/**
 * @Package: com.dobest.aspectdemo
 * @author: hujiansong
 * @date: 2018/8/8 14:45
 * @version: V1.0
 */
@Component
@Slf4j
@Aspect
public class DisplaySqlAspect {

    /**
     * 定义切点
     * <p>
     * 一种写法: execution(public * com.dobest.aspectdemo.web..*.*(..))
     * 第一个*代表所有返回值类型
     * 第二个*代表web包下所有的类
     * 第三个*代表web包下所有类下的所有方法
     * (..) 代表所有参数类型
     * <p>
     * 二种写法: @annotation(com.dobest.aspectdemo.DisplaySql)
     * 指代哪个注解，推荐使用这种方式，自定扫描
     */
    @Pointcut("@annotation(com.dobest.aspectdemo.DisplaySql)")
    public void logAnnotation() {
    }


    @Before(value = "logAnnotation()")
    public void before() {
        log.error("logAnnotation do before");
    }

    @Around(value = "logAnnotation()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        return joinPoint.proceed();
    }


    /**
     * 方法执行完成之后
     * @param joinPoint
     */
    @After(value = "logAnnotation()")
    public void after(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Annotation[] annotations = method.getAnnotations();
        for (int i = 0; i < annotations.length; i++) {
            Annotation annotation = annotations[i];
            if (annotation instanceof DisplaySql) {
                DisplaySql displaySql = (DisplaySql) annotation;
                boolean value = displaySql.value();
                if (value) {
                    log.error("method name is {}", signature.getMethod().getName());
                }
            }
        }

    }

    @AfterReturning(value = "logAnnotation()", returning = "obj")
    public void afterReturning(JoinPoint joinPoint, Object obj) {
        log.error("afterReturning return value {}", obj);
    }

}
